<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        
    </body>
    <script>
        /* 
        MVC模式:
            M -->   model -> 模型 -> 数据(js变量)
            V -->   View  -> 视图 -> 用户所见界面
            C -->   control -> 控制器 -> 相关事件交互,如果根据视图与用户交互后改变数据(通过DOM对象绑定事件,将变量进行修改)
        渐进式:
            1.易用  html css javascript
            2.高效  开发前端页面 非常高效 vue-router vuex   vue-cli
            3.灵活  开发灵活 多样性
        vue是一个javascript框架 js简化页面js操作
        vue渐进式javascript框架,操作很少的dom(虚拟dom),甚至不需要操作页面中任何dom元素,就完成数据和视图绑定---->双向数据绑定   MVVM
        MVVM模式
            Model:负责数据存储
            View:负责页面展示
            View Model:负责业务逻辑处理(比如ajax请求),对数据进行加工后交给视图展示
        一.VUE基础
            1.模板语法
                (1)插值
                v-once:通过使用 v-once 指令，你也能执行一次性地插值，当数据改变时，插值处的内容不会更新
                    a.文本  {{}}
                    b.纯html
                        v-html,防止xxs  csrf
                    c.表达式
                (2)指令
                    v-on:click  ----    @click
                    v-on 指令用于绑定HTML事件，其语法糖写法为用 @
                    v-bind      ----    :
                    v-bind指令用于设置HTML属性，其语法糖写法为用 ：
            ----------------------------------------------------------------------------------------
            条件渲染
                v-if:不显示时,第一次就直接不渲染,如果使内容已经显示将其改为不显示,将内容直接从dom去除,只是渲染一次的内容用v-if
                     v-if和v-else中间不能有其他元素
                v-show:不显示时,就会改为display:none,但是会渲染在dom上,反复需要切换的内容,使用v-show
                如果需要非常频繁地切换，则使用 v-show 较好；如果在运行时条件很少改变，则使用 v-if 较好。
            列表渲染
                v-for:指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法，其中 items 是源数据数组，而 item 则是被迭代的数组元素的别名
            侦听器
                虽然计算属性(computed)在大多数情况下更合适，但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法，来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时，这个方式是最有用的。
            Class 与 Style 绑定
                Vue.js 做了专门的增强。表达式结果的类型除了字符串之外，还可以是对象或数组。
			事件修饰符
				.stop		阻止冒泡
				.prevent	阻止默认事件  阻止提交
				.capture	事件捕获
				.self		v-on:click.prevent.self 会阻止所有的点击，而 v-on:click.self.prevent 只会阻止对元素自身的点击。
				.once		事件将只会触发一次
				.passive	修饰符尤其能够提升移动端的性能。(类似阻止默认事件的操作)


                .native   在我们需要监听一个组件的原生事件时,必须给对应的事件加上.native修饰符才能进行监听
                <back-top @click.native="backClick" v-show="isShowBackTop"></back-top>
                vue的组件进行监听点击事件是无效的,只要加上.native修饰符就行了
                click不能再组件上直接监听必须加上native   不能监听,必须加native
                
			按键修饰符    @keydown
				.enter	回车
				.tab
				.delete (捕获“删除”和“退格”键)
				.esc	
				.space	空格键
				.up		上
				.down	下
				.left	左
				.right	右
			系统修饰符
				.ctrl
				.alt
				.shift
				.meta
				----------------------------------------------------------
				.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件
			鼠标修饰符
				.left
				.right
				.middle
        */
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        /* 
            脚手架安装  Vue cli
                Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)

                全局安装 npm install -g @vue/cli

                vue --version    vue -V   这个命令来检查其版本是否正确

                在要创建项目的文件夹  按住shift + 鼠标右键  打开Powershell窗口

                -------------------------------------------------------------------------------------
                或者拉去vue cli 2
                        npm install -g @vue/cli-init
                vue cli2初始化项目:
                        vue init webpack my-project
                            1. 项目名字(回车)
                            2. 描述信息
                            3. 作者
                            4. Runtime-only  
                            5. vue-router Y
                            6. ESLint  n  严格模式
                            7. set up unit tests  y/n  单元测试  n
                            8. e2e Y/n 端到端测试
                            9. npm  yarn
                            10. 回车  构建项目   
                ---------------------------------------------------------------------------------
                cli3  创建项目

                运行以下命令来创建一个新项目    vue create 项目名称

                手动选择 Manually select features 回车  进入配置选项 按空格键是否选择  选过选项回车
                    Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) 
                    选着路由,yes:需要后端配置  地址:https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90    
                    no:不需要后端操作
                    Save this as a preset for future projects? (y/N)  需不需要保存选的选项的名字
                    访问地址不一样

                选择所有配置在一个文件,in package.json 回车
                
                依赖安装完毕之后,进入app文件夹

                npm run serve   启动

                npm run build   打包生成出来  成功之后  会多一个dist文件夹 
                 

                开发在src文件夹
                编译后dist文件夹里面的是放在服务器上的
            -------------------------------------------------------------------------------------------
            可视化创建
                vue ui
                http://localhost:8000           http://localhost:8000/project/select
                创建->在次创建新项目->输入项目名称->包管理工具->预设-> 创建项目,不保存预设->创建项目
        */
        //--------------------------------------------------------------------------------------------------------------------------------------------------------
        /* 
            解决install无反应，非报错问题。
            如果是npm和cnpm镜像出了问题，此篇不适用。

            之前有一个依赖，整理了一下文件夹，需要重新安装依赖， 遇到cnpm install无反应

            利用npm clean cache -f
            请一下缓存之后，就可以正常安装了。
        
         */
        /* 
            网页不会刷新   (栈结构    进栈-->出栈)  栈结构  先进后出
        赋值hash   哈希
            location.hash = ''
        HTML5的history模式:pushState
            history.pushState({},'','/foo')
            history.back() 等价于 history.go(-1);       后退(移除)
        HTML5的history模式:replaceState
            history.replaceState({},'','/foo')      不能使用后退功能
        HTML5的history模式:go
            history.back() 等价于 history.go(-1);       后退(移除)
            history.forward()  等价于 history.go(1);    前进(向前)
        ----------------------------------------------------------------------------------------
        传递参数的方式
            传递参数的方式有两种类型:params和query
            params的类型
                配置路由格式: /router/:id
                传递的方式:在path后面跟上对应的值
                传递后形成的路径:/router/123     /router/abc    /router/id
            query的类型
                配置路由格式:/router,也就是普通配置
                传递的方式:对象中使用query的key作为传递方式
                传递后形成的路径:/router?id=123   /router?id=abc
        */

        /* 
            Vuex是一个专为vue.js应用程序开发的状态管理模式
                它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种预测的方法发生变化

            运用场景:登陆状态/用户名称/头像/地理位置/商品收藏/购物车等

            单页面状态管理
                state，驱动应用的数据源；                           数据:data
                view，以声明方式将 state 映射到视图；                视图:模板
                actions，响应在 view 上的用户输入导致的状态变化。     交互:事件  反过来在修改 state

            state --> Vuecomponents --> actions --> mutations  --> state
            actions 异步操作    请求数据时
            mutations   同步操作   如果没有异步  Vue components 可以直接绕过 actions 到 mutations
            state --> Vuecomponents  --> mutations  --> state
        */ 
       /* 
            什么是$nextTick()
                类似于异步获取DOM的方法,常用于生命周期函数create中获取还未生成的Dom元素
                Vue在观察到数据变化时并不是直接更新DOM，而是开启一个队列，并缓冲在同一事件循环中发生的所有数据改变。
                理论上，我们不应主动去操作DOM，因为Vue的核心思想就是数据驱动DOM，但在很多业务里，我们避免不了会操做一些DOM,这时我们就有可能用到$nextTick。
                $nextTick方法作用,就是当页面上元素被重新渲染之后,才会指定回调函数中的代码
       */

        /* 
            axios
                安装: cnpm install axios --save
        
        
        */

        /* 
            从github拉项目没有node_modules 需要 cnpm install重新下载
        */
       /* 
        事件总线 $bus  非父子组件(cli4需要用到mitt代替$bus)
            事件总线是管理事件的   vuex是状态管理
            1.  发射    this.$bus.$emit('xxx',参数);
            2.  接收    this.$bus.$on('xxx',回调函数(参数))

            在main.js上添加:
                // 给 $bus  赋值Vue实例   事件总线
                Vue.prototype.$bus = new Vue();
       */
      /* 
        防抖debounce/节流throttle
            setTimeout(function(){
                // setTimeout里面的函数是一个异步函数
            })
            // 防抖js
            debounce(func,delay){
                let timer = null;
                return function(...args){
                    if(timer){
                        clearTimeout(timer);
                    }
                    timer = setTimeout(()=>{
                        func.apply(this,args);
                    },delay);
                }
            }
      
      */
      
       /* 
            移动端滚动  better-scroll
                npm install better-scrool --save
       
       */
        // 时间格式化的处理
       /* 
        console.log(this.$router);// new VueRouter()
        console.log(this.$route);//路由本身  当前路由处于活跃
       
       */

       //////////////////// 所有的组件都有一个属性:$el  用于获取组件中的元素
       ///////////////////  mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性：

        /* 

        // ...mapGetters方法将vuex中的getters中的计算属性转换成局部计算属性
        // 例如:getters中有cartLength/cartList 直接拿过来用  模板里面直接用getters的方法
        // 对象方法  数组方法
            vuex里面这样写:
                getters:{
                    cartLength(state){
                        return state.cartList.length
                    },
                    cartList(state){
                        return state.cartList
                    }
                }
            模板组件 里面这样写:
                computed:{
                    // 数组方法
                    ...mapGetters([
                        'cartLength'
                    ])
                    // 对象方法
                    ...mapGetters({
                        length:'cartLength',
                        list:'cartList'
                    })
                }
        */
        /* 
            监听每一张图片是否加载完成,只要一张图片加载完成了,就执行一次refresh()
                原生的js监听图片:img.onload = function()
                Vue中监听:@load = '方法'
                调用better-scroll的refresh()
        */
        /* 
                选中和不选中  一定要修改模型 给模型添加true或者false!!!!!不要修改样式

                

               ***************** 如果在vuex--->actions里面做了某个操作,想让外面知道完成了这个操作这里需要用到promise****************
               store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise
               !!!!!!!!!!  store.dispatch 仍旧返回 Promise：
        */
       /* 
                $toast 插件   自己封装
       */
        /* 
        在main.js执行
            解决移动端按钮300ms延迟
                npm install fastclick -S
                之后，在main.js中引入，并绑定到body。
                import FastClick from 'fastclick'
                FastClick.attach(document.body);　
                1.安装fastclick
                2.导入
                3.调用attach函数
        */
       /* 
            前三步在main.js执行,第4步 哪里的img需要在哪里修改
            vue-lazyload 图片懒加载使用
                1.安装  npm install vue-lazyload --save
                2.导入
                3.Vue.use
                4.修改img  :src  --->  v-lazy
       */
       /* 
            px2vw  单位转换插件
                npm install postcss-loader --save-dev
                npm install postcss-px-to-viewport --save-dev
            px2rem  单位转换插件
       */
        /* 
        登录与退出
            1.登陆业务流程
                在登陆页面输入用户名和密码
                调用后台接口进行验证
                通过验证之后,根据后台的响应状态跳转到项目主页
            2.登陆业务的相关技术点
                http是无状态的(如果登陆成功需要记录用户登陆状态)
                通过cookie在客户端记录状态
                通过session在服务端记录状态
                (前端和后台接口不存在跨域问题用 cookie  session来记录登陆状态)
                通过Token方式维持状态
                (前端和后台接口存在跨域问题用 token来记录登陆状态)
            3.登陆---->token原理分析
                (客户端)登录页面输入用户名和密码进行登陆--->(服务器)
                (客户端)<---服务器验证通过之后生成该用户的token并返回(服务器)  token是在服务器端生成的
                (客户端)客户端存储该token
                (客户端)--->后续所有的请求都携带该token发送请求(服务器)
                服务器端验证token是否通过(服务器)  通过证明已经登陆,然后根据token返回不同的数据
        
        
        切换时出现进度条
                cnpm install --save nprogress
                在 
                // 导入Nprogress包对应的js/css
                import Nprogress from "nprogress";
                import "nprogress/nprogress.css";
                需要配置拦截器 请求拦截器和响应拦截器
        
        */
        function sum(n) {
            console.log(n)
            if (n == 1) return 1
            return sum(n - 1) + n
            
        }
        sum(100)
        console.log(sum(100))
    </script>
</html> 
 

